

K.IsoImageSource = function(name, image, x, y, w, h, offsetX, offsetY){
	this.name = name;
	this.image = image;
	this.rect = new K.Rectangle(x, y, w, h, offsetX, offsetY);
	this.itemType = "land";
	this.walkable = true;
	this.itemH = 0;
};
K.IsoImageSource.prototype = K.cloneObject(K.ImageSource.prototype);
K.IsoImageSource.prototype.constructor = K.IsoImageSource;
K.IsoImageSource.prototype.itemType = null;
K.IsoImageSource.prototype.itemH = null;
K.IsoImageSource.prototype.walkable = null;



K.IsoSprite = function(name){
	this.initialize(name, {x:0, y:0, mapX:0, mapY:0, itemH:0, minH:0, imageSource:null});
};
K.IsoSprite.prototype = K.cloneObject(K.Sprite.prototype);
K.IsoSprite.prototype.constructor = K.IsoSprite;
K.IsoSprite.prototype.c = 0;
K.IsoSprite.prototype.r = 0;
K.IsoSprite.prototype.mapX = null;
K.IsoSprite.prototype.mapY = null;
K.IsoSprite.prototype.mapW = null;
K.IsoSprite.prototype.mapH = null;
K.IsoSprite.prototype.itemH = null;
K.IsoSprite.prototype.minH = null;
K.IsoSprite.prototype.walkable = true;
K.IsoSprite.prototype.slope = null;
K.IsoSprite.prototype.itemType = null;
K.IsoSprite.prototype.setImageSource = function(v){
	if (v != null){
		this.localRect.x = v.offsetX;
		this.localRect.y = v.offsetY;
		this.localRect.width = v.width;
		this.localRect.height = v.height;
		this.itemType = v.itemType;
		if (v.itemType != "dynamic") this.walkable = v.walkable;
		this.itemH = v.itemH ? v.itemH : 1;
		this.slope = v.slope ? v.slope : "none"; 
	} else {
		this.walkable = true;
		this.slope = "none";
		this.itemH = 0;
		this.minH = 0;
		this.itemType = "land";
		this.localRect.x = 0;
		this.localRect.y = 0;
		this.localRect.width = 0;
		this.localRect.height = 0;
	}
	this.src = v;
};



/*
** ____________________________________________________________________________________
** ISO
** Athor mi_kuncoro@yahoo.co.id
** Version 1.0
** _____________________________________________________________________________________
**
** A pluggin for K.js to make isometric application.
** Keep as simple as we can but satisfy common needs.
**
** ISO class constructor
** @param tileScreenWidth = The screen width of a tile in pixel
** @param tileScreenHeight = The screen height of a tile in pixel
** @param tilePerRow = Number of tile per row and number of row (it's assumed as square)
**
** Properties:
** tileW = The screen width of a tile in pixel
** tileH = The screen height of a tile in pixel
** tileM = The 2D Map height and width of a tile. AAuto created.
** matrixP = Iso project matrix. Auto created.
** matrixI = Iso unproject matrix. Auto created.
** lands = Array of land/surface items. Read only.
** statics = Array of static items.
** dynamics = Array of dynamic items.
** sheets = Array of ImageSource.
** container =	Sprite as container of iso-items.
** 				Add it to stage or a child of K.stage to display.
** scrollX = Get and set container scroll x value.
** scrollY = Get and set container scroll x value.
**
** Methods:
**
** createName = Utility to create a name based on column index and row index.
** @param prefix = Prefix of the name.
** @param c = column index.
** @param r = row index.
** @return string of the name.
** 
** getTileImageSource = To get a land's ImageSource based on index.
** 
** getTileAtMouse = To get tile at mouse position.
** @param x = Mouse x position in stage.
** @param y = Mouse y position in stage.
** @return the tile or null if not exist.
**
** getTileAtLocal = To get tile at a point in map 2D.
** @param x = Mouse x position in map.
** @param y = Mouse y position in map.
** @return the tile or null if not exist.
**
** getTileAtCR = To get tile based on column index and row index
** @param c = column index.
** @param r = row index.
** @return the tile or null if not exist.
**
** 
*/
K.Iso =  function(tileScreenWidth, tileScreenHeight, tilePerRow){
	this.numPR = tilePerRow;
	this.tileW = tileScreenWidth;
	this.tileH = tileScreenHeight;
	this.tileM = Math.sqrt(tileScreenWidth * tileScreenWidth / 2);
	this.matrixP = new K.Matrix();
	this.matrixP.rotate(K.P45);
	this.matrixP.scale(1.0, 0.5);
	this.matrixI = this.matrixP.clone();
	this.matrixI.invert();
	this.container = new K.Sprite("isoContainer", 0, 0);
	this.sheet = [];
	this.lands = [];
	this.statics = [];
	this.dynamics = [];
	
	var c, r, p, pp, o;
	var p = {x:0, y:0};
	for (r = 0; r < this.numPR; r++){
		p.y = r * this.tileM;
		for (c = 0; c < this.numPR; c++){
			p.x = c * this.tileM;
			o = new K.IsoSprite(this.createName("land", c, r));
			o.c = c;
			o.r = r;
			o.mapX = p.x;
			o.mapY = p.y;
			o.mapW = this.tileM;
			o.mapH = this.tileM;
			o.itemType = "land";
			o.walkable = true;
			this.addItem(o);
		}
	}
};
K.Iso.prototype = {
	constructor:K.Iso,
	tileW:0, tileH:0, tileM:0, numPR:0,
	matrixP:null, matrixI:null,
	lands:null, statics:null, dynamics:null,
	sheet:null,
	container:null,
	get items() { return this.container.children.array; },
	get scrollX() { return this.container.x; },
	set scrollX(v) { this.container.x = v; },
	get scrollY() { return this.container.y; },
	set scrollY(v) { this.container.y = v; },
	createName:function(prefix, c, r){
		return prefix + "_" + c.toString() + "_" + r.toString();
	},
	getTileImageSource:function(v){
		return this.sheet[v];
	},
	getTileAtCR:function(c, r){
		return this.container.getChildByName(this.createName("land", c, r));
	},
	getTileAtLocal:function(x, y){
		return this.getTileAtCR(Math.floor(x / this.tileM), Math.floor(y / this.tileM));
	},
	getTileAtMouse:function(x, y){
		var p = this.container.globalToLocal(x, y);
		p = this.matrixI.transformPoint(p.x, p.y);
		return this.getTileAtLocal(p.x, p.y);
	},
	getSurfaceHeightAt:function(x, y){
		var t = this.getTileAtLocal(x, y);
		if (t == null) return 0;
		var h = t.minH + t.itemH;
		switch (t.slope){
			case "none": break;
			case "right":
				h = ( 1 - ( (x - t.mapX)/this.tileM ) ) * t.itemH + t.minH;
				break;
			case "left":
				h = ( (x - t.mapX)/this.tileM ) * t.itemH + t.minH;
				break;
			case "down":
				h = ( 1 - ( (y - t.mapY)/this.tileM ) ) * t.itemH + t.minH;
				break;
			case "up":
				h = ( (y - t.mapY)/this.tileM ) * t.itemH + t.minH;
				break;
			default:
				console.log(t.slope);
				break;
		}
		return h;
	},
	addItem:function(v){
		if (v.itemType == "land") {
			this.lands.push(v);
		} else if (v.itemType == "static") {
			this.statics.push(v);
		} else if (v.itemType == "dynamic") {
			this.dynamics.push(v);
		} else {
			alert("Item type " + v.itemType + " unknown");
			return;
		}
		this.container.addChild(v);
	},
	removeItem:function(v){
		var i = -1;
		if (v.itemType == "land") {
			i = this.lands.indexOf(v);
			if (i > -1) this.lands.splice(i, 1);
		} else if (v.itemType == "static") {
			i = this.statics.indexOf(v);
			if (i > -1) this.lands.splice(i, 1);
		} else if (v.itemType == "dynamic") {
			i = this.dynamics.indexOf(v);
			if (i > -1) this.lands.splice(i, 1);
		} else {
			alert("Item type " + v.itemType + " unknown");
			return;
		}
		this.container.removeChildByName(v.name);
		v.dispose();
	},
	projectItem:function(o){
		if (o.minH == undefined) o.minH = 0;
		var p = this.matrixP.transformPoint(o.mapX, o.mapY);
		o.x = p.x;
		o.y = p.y - o.minH;
		o.zIndex = p.y;
		if (o.itemType == "land") o.zIndex -= 1;
	},
	projectItems:function(){
		var a = this.container.children.array;
		while (a.length > 0) {
			this.projectItem(a.pop());
		}
	}
};

